#include "ManejadorEstructurasLibres.h"

ManejadorEstructurasLibres::ManejadorEstructurasLibres(string path) {

	this->path = path;
	bool archivoNuevo = this->abrirArchivo();
	if(archivoNuevo){
		this->cantidadEstructurasLibres = 0;
		this->estructurasLibres.write((char*) &(this->cantidadEstructurasLibres), sizeof(int));
	} else {
        this->estructurasLibres.seekg(0, ios::beg);
        this->estructurasLibres.read((char*) &(this->cantidadEstructurasLibres), sizeof(int));
	}
	this->cerrarArchivo();

}

/* Abre un archivo en modo binario, lectura y escritura, y posiciona los punteros de lectura y de escritura en el EOF.
 * Si el archivo no existe lo crea. */
bool ManejadorEstructurasLibres::abrirArchivo() {

	char* primerCaracterDelPath = &(this->path[0]);
    bool nuevo = false;
	this->estructurasLibres.open(primerCaracterDelPath, ios::binary | ios::in | ios::out);

	if (this->estructurasLibres.fail())
	{
		this->estructurasLibres.clear();
		this->estructurasLibres.open(primerCaracterDelPath, ios::binary | ios::trunc | ios::in | ios::out);
		nuevo= true;
	}
	return nuevo;
}

/* Cierra el archivo y lo limpia (por si quedó lockeado por alguna *extraña* razón) */
void ManejadorEstructurasLibres::cerrarArchivo() {
	this->estructurasLibres.clear();
	this->estructurasLibres.close();
}

int ManejadorEstructurasLibres::obtenerEstructuraLibre(){

	if(this->getCantidadEstructurasLibres()> 0){

		this->abrirArchivo();

		int posicionEstructuraLibre = (this->getCantidadEstructurasLibres() * 4);
		this->estructurasLibres.seekg(posicionEstructuraLibre, ios::beg);
		int numeroEstructuraLibre;
        this->estructurasLibres.read((char*) &(numeroEstructuraLibre), sizeof(int));

        // Disminuyo la cantidad y actualizo el archivo
        this->cantidadEstructurasLibres += -1;
    	this->estructurasLibres.seekp(0, ios::beg);
    	this->estructurasLibres.write((char*) &(this->cantidadEstructurasLibres), sizeof(int));

        this->cerrarArchivo();
        return numeroEstructuraLibre;
	}else
		return -1;

}
void ManejadorEstructurasLibres::insertarEstructuraLibre(int numeroEstructuraLibre){

	this->abrirArchivo();

	int posicionEscritura = (this->getCantidadEstructurasLibres() * 4)+ 4;
	this->estructurasLibres.seekp(posicionEscritura,ios::beg);
	this->estructurasLibres.write((char*)& numeroEstructuraLibre,sizeof(int));

	// Aumento la cantidad y actualizo el archivo
	this->cantidadEstructurasLibres +=1;
	this->estructurasLibres.seekp(0, ios::beg);
	this->estructurasLibres.write((char*) &(this->cantidadEstructurasLibres), sizeof(int));

	this->cerrarArchivo();

}

vector<int>* ManejadorEstructurasLibres::getListaEstructurasLibres(){

	    this->abrirArchivo();
        vector<int> * estructurasLibres = new vector<int>;
        this->estructurasLibres.seekg(sizeof(int),ios::beg);
        for(int i =0; i< this->getCantidadEstructurasLibres(); i++){
                int numeroEstructura;
                this->estructurasLibres.read((char*)&numeroEstructura,sizeof(int));
                estructurasLibres->push_back(numeroEstructura);
        }
        this->cerrarArchivo();

        return estructurasLibres;

}

int ManejadorEstructurasLibres::getCantidadEstructurasLibres(){
	return this->cantidadEstructurasLibres;
}

void ManejadorEstructurasLibres::truncarArchivo(){
	this->abrirArchivo();
	 this->estructurasLibres.seekp(0, ios::end);
	 int tamanioArchivo = this->estructurasLibres.tellp();
	 if ((tamanioArchivo/4) > this->getCantidadEstructurasLibres() ){
		 //truncar el archivo
	 }
}

ManejadorEstructurasLibres::~ManejadorEstructurasLibres() {

}
